package ch.ti.bfh.app.loodel.web.controller;


import ch.ti.bfh.app.loodel.service.vote.AllMembersTimeSlotVotesData;
import ch.ti.bfh.app.loodel.service.vote.CurrentMemberTimeSlotVoteData;
import ch.ti.bfh.app.loodel.service.vote.LearningEventVoteData;
import ch.ti.bfh.app.loodel.service.vote.LearningEventVoteService;
import ch.ti.bfh.app.loodel.web.model.LearningEventVoteModel;
import ch.ti.bfh.app.loodel.web.model.LoodelScheduleEvent;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.primefaces.event.ScheduleEntrySelectEvent;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.faces.context.FacesContext;
import javax.inject.Inject;
import java.util.List;

@Component
@Scope("request")
public class LearningEventVoteController {

    private final LearningEventVoteModel learningEventVoteModel;

    private final LearningEventVoteService learningEventVoteService;

    @Inject
    public LearningEventVoteController(LearningEventVoteModel learningEventVoteModel, LearningEventVoteService learningEventVoteService) {
        this.learningEventVoteModel = learningEventVoteModel;
        this.learningEventVoteService = learningEventVoteService;
    }

    public void enterLearningEventIdAction() {
        initLearningEventVoteData();
    }

    public void init() {
        if (FacesContext.getCurrentInstance().isPostback() == false) {
            initLearningEventVoteData();
        }
    }

    private void initLearningEventVoteData() {
        if (StringUtils.isNotEmpty(learningEventVoteModel.getLearningEventId())) {
            initLearningEventSummary();
            initSchedule();
            initDataList();
        }
    }

    private void initLearningEventSummary() {
        LearningEventVoteData learningEventVoteData = learningEventVoteService.getLearningEventVoteData(learningEventVoteModel.getLearningEventId());
        this.learningEventVoteModel.setLearningEventVoteData(learningEventVoteData);

    }


    public void onTabChange(TabChangeEvent event) {
        initSchedule();
        initDataList();
    }


    public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {
        ScheduleEvent scheduleEvent = selectEvent.getScheduleEvent();
        CurrentMemberTimeSlotVoteData currentMemberTimeSlotVoteData = (CurrentMemberTimeSlotVoteData) scheduleEvent.getData();
        Long timeSlotId = currentMemberTimeSlotVoteData.getTimeSlotData().getTimeSlotId();
        if (currentMemberTimeSlotVoteData.isCurrentMemberVoted()) {
            learningEventVoteService.removeYourTimeSlotVote(timeSlotId);
        } else {
            learningEventVoteService.giveYourTimeSlotVote(timeSlotId);
            currentMemberTimeSlotVoteData.setCurrentMemberVoted(true);
        }
        CurrentMemberTimeSlotVoteData updatedCurrentMemberTimeSlotVoteData = learningEventVoteService.getCurrentMemberTimeSlotVote(timeSlotId);
        final LoodelScheduleEvent scheduleEventWithExistingId = LoodelScheduleEventFactory.createNewScheduleEventWithExistingId(updatedCurrentMemberTimeSlotVoteData, scheduleEvent.getId(), true);
        learningEventVoteModel.getScheduleModel().updateEvent(scheduleEventWithExistingId);
        this.initLearningEventSummary();
    }

    private void initDataList() {
        final String learningEventId = learningEventVoteModel.getLearningEventId();
        List<AllMembersTimeSlotVotesData> allMembersTimeSlotVotes = learningEventVoteService.getAllMembersTimeSlotVotes(learningEventId);
        this.learningEventVoteModel.setAllMembersTimeSlotVotesDataList(allMembersTimeSlotVotes);

    }

    private void initSchedule() {
        final String learningEventId = learningEventVoteModel.getLearningEventId();
        DefaultScheduleModel scheduleModel = new DefaultScheduleModel();
        this.learningEventVoteModel.setScheduleModel(scheduleModel);
        List<CurrentMemberTimeSlotVoteData> currentMemberTimeSlotVoteDataList = learningEventVoteService.getCurrentMemberTimeSlotVotes(learningEventId);
        DateTime firstDateTime = new DateTime();
        for (CurrentMemberTimeSlotVoteData currentMemberTimeSlotVoteData : currentMemberTimeSlotVoteDataList) {
            DateTime start = currentMemberTimeSlotVoteData.getTimeSlotData().getDateTimeInterval().getStart();
            if (start.isBefore(firstDateTime)) {
                firstDateTime = start;
            }
            scheduleModel.addEvent(LoodelScheduleEventFactory.createNewScheduleEvent(currentMemberTimeSlotVoteData, true));
        }
        learningEventVoteModel.setInitialDate(firstDateTime.toDate());
    }


}
